package tsg.graphic;

import java.util.Stack;

import tsg.util.Point;

// TODO: Make a quick algorithm, that uses ray casting (essentially) to fill, not as accurate, but MUCH faster
public class VerticalGradient extends Gradient
{
	public VerticalGradient(int position1, Color color1, int position2, Color color2) 
	{
		super(position1, color1, position2, color2);
	}

	public void fill (Graphics g, Point origin, boolean[][] boundingMap)
	{
		Color[] 	 gradientMap  = super.getGradientMap();		
		boolean[][]  fillMap      = new boolean[boundingMap.length][boundingMap[0].length];
		int          width        = fillMap[0].length;
		int          height       = fillMap.length;
		Stack<Point> needToFill   = new Stack<Point>();
		Point        currentPoint = origin;
		
		g.setColor(this);
		
		needToFill.add(currentPoint);
		
		
		while(needToFill.size() > 0)
		{
			// Get the current working point
			currentPoint = needToFill.pop();
			
			if(currentPoint.getY() >= this.getPosition1())
			{
				if(currentPoint.getY() <= this.getPosition2())
				{
					g.setColor(gradientMap[currentPoint.getY() - this.getPosition1()]);
				}
				else
				{
					g.setColor(gradientMap[gradientMap.length-1]);
				}
			}
			else
			{
				g.setColor(gradientMap[0]);
			}
			
			// Paint this point
			g.drawLine(currentPoint.getX(), currentPoint.getY(), currentPoint.getX(), currentPoint.getY());
			
			// Mark this point as filled
			fillMap[currentPoint.getY()][currentPoint.getX()] = true;
			
			// Do we need to fill upward?
			if( currentPoint.getY() 									>  0				&&  // Make sure we are not at the top
				fillMap[currentPoint.getY()-1][currentPoint.getX()]		== false			&&	// Make sure the pixel above has not yet been filled
				boundingMap[currentPoint.getY()-1][currentPoint.getX()]	== false			)	// Make sure the pixel above is not bounded
			{
				needToFill.add(new Point(currentPoint.getX(), currentPoint.getY()-1));
			}


			// Do we need to fill downward?
			if( currentPoint.getY() 									<  height			&&  // Make sure we are not at the bottom
				fillMap[currentPoint.getY()+1][currentPoint.getX()]		== false			&&	// Make sure the pixel below has not yet been filled
				boundingMap[currentPoint.getY()+1][currentPoint.getX()]	== false			)	// Make sure the pixel below is not bounded
			{
				needToFill.add(new Point(currentPoint.getX(), currentPoint.getY()+1));
			}
			
			
			// Do we need to fill left?
			if( currentPoint.getX() 									>  0				&&  // Make sure we are not at the left
				fillMap[currentPoint.getY()][currentPoint.getX()-1]		== false			&&	// Make sure the pixel left has not yet been filled
				boundingMap[currentPoint.getY()][currentPoint.getX()-1]	== false			)	// Make sure the pixel left is not bounded
			{
				needToFill.add(new Point(currentPoint.getX()-1, currentPoint.getY()));
			}
			
			
			// Do we need to fill right?
			if( currentPoint.getY() 									<  width			&&  // Make sure we are not at the right
				fillMap[currentPoint.getY()][currentPoint.getX()+1]		== false			&&	// Make sure the pixel right has not yet been filled
				boundingMap[currentPoint.getY()][currentPoint.getX()+1]	== false			)	// Make sure the pixel right is not bounded
			{
				needToFill.add(new Point(currentPoint.getX()+1, currentPoint.getY()));
			}	
		}
	}
}
